#define QUAD_VERTICES (4)

// Quad width is equal to quad height
// We cache here its half size
#define QUAD_HALF_SIZE (1.0f)

cbuffer cbPerFrame : register (b0) {
	float4x4 gView;
	float4x4 gProj;
};

struct GSInput {
	float3 mQuadCenterPosW : POSITION;
};

struct GSOutput {
	float4 mVertexPosH : SV_POSITION;
	float2 mVertexTexC : TEXCOORD;
};

[maxvertexcount(QUAD_VERTICES)]
void 
main(const in point GSInput input[1], inout TriangleStream<GSOutput> triangleStream) {
	// Compute quad center position in view space.
	// Then we can easily build a quad (two triangles) that face the camera.
	const float4 mQuadCenterPosV = mul(float4(input[0].mQuadCenterPosW, 1.0f), gView);

	// Compute vertices positions and texture coordinates based on
	// a quad whose center position is mQuadCenterPosV
	GSOutput output;

	output.mVertexPosH = mul(mQuadCenterPosV + float4(-QUAD_HALF_SIZE, QUAD_HALF_SIZE, 0.0f, 0.0f), gProj);
	output.mVertexTexC = float2(0.0f, 1.0f);
	triangleStream.Append(output);

	output.mVertexPosH = mul(mQuadCenterPosV + float4(QUAD_HALF_SIZE, QUAD_HALF_SIZE, 0.0f, 0.0f), gProj);
	output.mVertexTexC = float2(1.0f, 1.0f);
	triangleStream.Append(output);

	output.mVertexPosH = mul(mQuadCenterPosV + float4(-QUAD_HALF_SIZE, -QUAD_HALF_SIZE, 0.0f, 0.0f), gProj);
	output.mVertexTexC = float2(0.0f, 0.0f);
	triangleStream.Append(output);

	output.mVertexPosH = mul(mQuadCenterPosV + float4(QUAD_HALF_SIZE, -QUAD_HALF_SIZE, 0.0f, 0.0f), gProj);
	output.mVertexTexC = float2(1.0f, 0.0f);
	triangleStream.Append(output);

	triangleStream.RestartStrip();
}